/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.nifi.controller.repository.claim;

import java.util.Collection;
import java.util.concurrent.TimeUnit;

/**
 * Responsible for managing all ResourceClaims that are used in the application //用于管理应用中所有的ResourceClaims
 */
public interface ResourceClaimManager {

    /**
     * Creates a new Resource Claim with the given id, container, section, and //根据给定的ID,container,section和丢失容忍度创建一个新的Resource Claim
     * loss tolerance.
     *
     * @param id of claim
     * @param container of claim
     * @param section of claim
     * @param lossTolerant of claim
     * @param writable whether or not the claim should be made writable //新建的claim是否可写
     * @return new claim
     */
    ResourceClaim newResourceClaim(String container, String section, String id, boolean lossTolerant, boolean writable);

    /**
     * Returns the Resource Claim with the given id, container, and section, if one exists, <code>null</code> otherwise
     * //如果存在,返回指定id,container,section的Resource Claim;否则返回null
     * @param id of claim
     * @param container of claim
     * @param section of claim
     * @return the existing resource claim or <code>null</code> if none exists
     */
    ResourceClaim getResourceClaim(String container, String section, String id);


    /**
     * @param claim to obtain reference count for //需要计算的claim
     * @return the number of FlowFiles that hold a claim to a particular piece //返回持有claim的flowfile数
     * of FlowFile content
     */
    int getClaimantCount(ResourceClaim claim);

    /**
     * Decreases by 1 the count of how many FlowFiles hold a claim to a //将持有claim的flowfile数减一
     * particular piece of FlowFile content and returns the new count
     *
     * @param claim to decrement claimants on
     * @return new claimant count
     */
    int decrementClaimantCount(ResourceClaim claim);

    /**
     * Increases by 1 the count of how many FlowFiles hold a claim to a //将持有claim的flowfile数加1
     * particular piece of FlowFile content and returns the new count
     *
     * @param claim to increment claims on
     * @return new claimant count
     */
    int incrementClaimantCount(ResourceClaim claim);

    /**
     * Increases by 1 the count of how many FlowFiles hold a claim to a //将持有claim的flowfile数加1
     * particular piece of FlowFile content and returns the new count.
     *
     * If it is known that the Content Claim whose count is being incremented is //如果这个ResourceClaim的新建的
     * a newly created ResourceClaim, this method should be called with a value //第二个参数设置为true
     * of {@code true} as the second argument, as it may allow the manager to //管理员可据此优化任务
     * optimize its tasks, knowing that the Content Claim cannot be referenced //因为这个新建的ContentClaim
     * by any other component //没有被其他组件引用
     *
     * @param claim to increment
     * @param newClaim provides a hint that no other process can have access to this //目前是否有其他进程访问该claim
     *            claim right now
     * @return new claim count
     */
    int incrementClaimantCount(ResourceClaim claim, boolean newClaim);

    /**
     * Indicates that the given ResourceClaim can now be destroyed by the //表明指定的ResourceClaim可以被Content Repository销毁了
     * appropriate Content Repository. This should be done only after it is //需要保证FlowFile仓库已经与底层存储同步之后才能做。
     * guaranteed that the FlowFile Repository has been synchronized with its //
     * underlying storage component. This way, we avoid the following sequence
     * of events:
     * <ul>
     * <li>FlowFile Repository is updated to indicate that FlowFile F no longer depends on ResourceClaim C</li> //更新FlowFile仓库表明FlowFile F不再依赖ResourceClaim C
     * <li>ResourceClaim C is no longer needed and is destroyed</li> //ResourceClaim C不再需要，可以销毁
     * <li>The Operating System crashes or there is a power failure</li> //操作系统崩溃或者掉电，重启时FlowFile仓库没有与底层存储同步，这就意味着FlowFile F需要ResourceClaim C
     * <li>Upon restart, the FlowFile Repository was not synchronized with its underlying storage mechanism and as such indicates that FlowFile F needs ResourceClaim C.</li>
     * <li>Since ResourceClaim C has already been destroyed, it is inaccessible, and FlowFile F's Content is not found, so the FlowFile is removed, resulting in data loss.</li>
     * </ul> //但是ResourceClaim C已经被销毁了，不可访问，FlowFile F的内容找不到了，这样一来FlowFile就会被删掉，导致数据丢失
     *
     * <p> //应该只在下列情况下标记ResourceClaim为可销毁的：FlowFile仓库已经与底层存储机制完成同步，重启的时候，不会执行不必要的Claim
     * Using this method of marking the ResourceClaim as destructable only when the FlowFile repository has been synced with the underlying storage mechanism, we can ensure that on restart, we will
     * not point to this unneeded claim. As such, it is now safe to destroy the contents. //这样就可以安全地销毁Content
     * </p>
     *
     * @param claim to mark as now destructable //需要标记销毁的claim
     */
    void markDestructable(ResourceClaim claim);

    /**
     * Drains up to {@code maxElements} Content Claims from the internal queue //从内部待销毁队列中消费最多
     * of destructable content claims to the given {@code destination} so that //maxElements个ContentClaim到给定的目的地
     * they can be destroyed. //这样它们就可以被销毁了
     *
     * @param destination to drain to
     * @param maxElements max items to drain
     */
    void drainDestructableClaims(Collection<ResourceClaim> destination, int maxElements);

    /**
     * Drains up to {@code maxElements} Content Claims from the internal queue //从内部待销毁队列中消费最多
     * of destructable content claims to the given {@code destination} so that //maxElements个ContentClaim到给定的目的地
     * they can be destroyed. If no ResourceClaim is ready to be destroyed at //这样它们就可以被销毁了.如果目前没有ResourceClaim可以销毁
     * this time, will wait up to the specified amount of time before returning. //在返回之前会等待指定的时间
     * If, after the specified amount of time, there is still no ResourceClaim //如果到了指定的时间，依然没有可以
     * ready to be destroyed, the method will return without having added //销毁的ResourceClaim，方法直接返回
     * anything to the given {@code destination}. //destination中不会添加任何东西
     *
     * @param destination to drain to
     * @param maxElements max items to drain
     * @param timeout maximum time to wait
     * @param unit unit of time to wait
     */
    void drainDestructableClaims(Collection<ResourceClaim> destination, int maxElements, long timeout, TimeUnit unit);

    /**
     * Clears the manager's memory of any and all ResourceClaims that it knows
     * about
     */
    void purge();

    /**
     * Freezes the Resource Claim so that it can no longer be written to //冻结某个ResourceClaim，不再写入
     *
     * @param claim the resource claim to freeze
     */
    void freeze(ResourceClaim claim);
}
